package com.atguigu.spzx.service.sms.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.atguigu.commom.utils.HttpUtils;
import com.atguigu.commom.utils.RegexValidateUtils;
import com.atguigu.spzx.service.sms.properties.SpzxSmsProperties;
import com.atguigu.spzx.service.sms.service.SmsService;
import com.atguigu.spzx.common.handler.exception.SpzxException;
import com.atguigu.spzx.model.common.ResultCodeEnum;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * title:
 * author: zgl
 * date: 2024/1/16
 * description：
 */
@Service
public class SmsServiceImpl implements SmsService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void sendCode(String phone, Integer type) {
        //验证手机号格式
        if (!RegexValidateUtils.checkCellphone(phone)) {
            throw new SpzxException(ResultCodeEnum.PHONE_NUM_ERROR);
        }
        //判断需要验证码的类型
        if (type == null) {
            //注册
            sendNumberCode(phone, type);
        } else {
            //登录
        }
    }

    private void sendNumberCode(String phone, Integer type) {
        String countKey = "spzx:code:count" + phone;
        String limitKey = "spzx:code:limit" + phone;
        if (stringRedisTemplate.hasKey(limitKey)) {
            throw new SpzxException(ResultCodeEnum.SEND_MESSAGE_LIMIT_ERROR);
        }
        String count = stringRedisTemplate.opsForValue().get(countKey);
        if (!StringUtils.isEmpty(count) && Integer.parseInt(count) >= 3) {
            throw new SpzxException(ResultCodeEnum.SEND_MESSAGE_COUNT_ERROR);
        }
        //"CST_qozfh101"
        //"code:1234,expire_at:5"
        long expireTime = 20;
        String code = RandomUtil.randomNumbers(4);
        String content = "code:" + code + ",expire_at:" + expireTime;
        String templateId = SpzxSmsProperties.TEMPLATE_ID;
        //生成验证码
        sendMessageByApi(content, templateId, phone);
        //存入redis
        stringRedisTemplate.opsForValue().set("spzx:code:register" + phone, code, expireTime, TimeUnit.MINUTES);
        //count和limit
        Long increment = stringRedisTemplate.opsForValue().increment(countKey);
        if (increment.intValue() == 1) {
            stringRedisTemplate.expire(countKey, 1, TimeUnit.DAYS);
        }
        stringRedisTemplate.opsForValue().set(limitKey, "1", 5, TimeUnit.MINUTES);

    }

    private Boolean sendMessageByApi(String content, String templateId, String phone) {
        String host = SpzxSmsProperties.HOST;
        String path = SpzxSmsProperties.PATH;
        String method = SpzxSmsProperties.METHOD;
        String appcode = SpzxSmsProperties.APPCODE;
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        //根据API的要求，定义相对应的Content-Type
        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        //"code:1234,expire_at:5"
        bodys.put("content", content);
        //"CST_qozfh101"
        bodys.put("template_id", templateId);  //该模板为调试接口专用，短信下发有受限制，调试成功后请联系客服报备专属模板
        bodys.put("phone_number", phone);
        try {
            /**
             * 重要提示如下:
             * HttpUtils请从
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
             * 下载
             *
             * 相应的依赖请参照
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
             */
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            System.out.println(response.toString());
            //获取response的body
//            System.out.println(EntityUtils.toString(response.getEntity()));
            //获取状态码
            int statusCode = response.getStatusLine().getStatusCode();
            String entity = EntityUtils.toString(response.getEntity());
            Map map = JSON.parseObject(entity, Map.class);
            if (!(statusCode == 200 && "OK".equals(map.get("status")))) {
                throw new SpzxException(ResultCodeEnum.SEND_MESSAGE_FAIL);
            }
            return true;
        } catch (Exception e) {
//            e.printStackTrace();
            throw new SpzxException(ResultCodeEnum.SEND_MESSAGE_FAIL, e);
        }
    }
}
